from flask import request, jsonify, g
from flask_jwt_extended import jwt_required
import datetime
from bson import ObjectId
import re

from app.api.v1 import api_bp
from app import mongo
from app.utils.auth import permission_required
from app.schemas.patient import PatientSchema, PatientUpdateSchema
from app.utils.common import normalize_data, paginate, generate_id, parse_query_params

@api_bp.route('/patients', methods=['GET'])
@jwt_required()
@permission_required('patient:read')
def get_patients():
    """获取患者列表"""
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'registrationDate')
    order = request.args.get('order', 'desc')
    
    # 解析过滤参数
    query = {}
    
    # 名称搜索
    name = request.args.get('name')
    if name:
        query['name'] = {'$regex': name, '$options': 'i'}
    
    # 是否活跃
    active_status = request.args.get('activeStatus')
    if active_status:
        query['activeStatus'] = active_status.lower() == 'true'
    
    # 标签搜索
    tag = request.args.get('tag')
    if tag:
        query['tags'] = tag
    
    # 身份证号搜索
    id_number = request.args.get('idNumber')
    if id_number:
        query['idNumber'] = {'$regex': id_number, '$options': 'i'}
    
    # 手机号搜索
    phone = request.args.get('phone')
    if phone:
        query['contactInfo.phone'] = {'$regex': phone, '$options': 'i'}
    
    # 确定排序
    sort_direction = -1 if order.lower() == 'desc' else 1
    
    # 获取数据
    patients_cursor = mongo.db.patients.find(query).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(patients_cursor, page, limit)
    
    # 标准化数据
    normalized_items = [normalize_data(item) for item in paginated_data['items']]
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'patients': normalized_items
        }
    }), 200

@api_bp.route('/patients', methods=['POST'])
@jwt_required()
@permission_required('patient:create')
def create_patient():
    """创建新患者"""
    # 验证请求数据
    schema = PatientSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 检查身份证号是否已存在
    if mongo.db.patients.find_one({'idNumber': data['idNumber']}):
        return jsonify({
            'success': False,
            'message': '该身份证号已存在'
        }), 400
    
    # 生成患者ID
    data['patientId'] = generate_id('P')
    
    # 设置创建时间和更新时间
    now = datetime.datetime.utcnow()
    data['createdAt'] = now
    data['updatedAt'] = now
    data['registrationDate'] = now
    
    # 默认设为活跃状态
    if 'activeStatus' not in data:
        data['activeStatus'] = True
    
    # 保存到数据库
    result = mongo.db.patients.insert_one(data)
    
    return jsonify({
        'success': True,
        'message': '患者创建成功',
        'data': {
            'id': str(result.inserted_id),
            'patientId': data['patientId'],
            'name': data['name'],
            'createdAt': now.isoformat()
        }
    }), 201

@api_bp.route('/patients/<id>', methods=['GET'])
@jwt_required()
@permission_required('patient:read')
def get_patient(id):
    """获取单个患者信息"""
    # 尝试按ID查找
    patient = None
    
    # 如果是有效的ObjectId，按_id查找
    if ObjectId.is_valid(id):
        patient = mongo.db.patients.find_one({'_id': ObjectId(id)})
    
    # 如果没找到，尝试按patientId查找
    if not patient:
        patient = mongo.db.patients.find_one({'patientId': id})
    
    # 如果还没找到，尝试按身份证号查找
    if not patient and re.match(r'^\d{17}[\dXx]$', id):
        patient = mongo.db.patients.find_one({'idNumber': id})
    
    if not patient:
        return jsonify({
            'success': False,
            'message': '患者不存在'
        }), 404
    
    # 标准化数据
    normalized_patient = normalize_data(patient)
    
    return jsonify({
        'success': True,
        'data': normalized_patient
    }), 200

@api_bp.route('/patients/<id>', methods=['PUT'])
@jwt_required()
@permission_required('patient:update')
def update_patient(id):
    """更新患者信息"""
    # 验证请求数据
    schema = PatientUpdateSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 查找患者
    patient = None
    if ObjectId.is_valid(id):
        patient = mongo.db.patients.find_one({'_id': ObjectId(id)})
    
    if not patient:
        patient = mongo.db.patients.find_one({'patientId': id})
    
    if not patient:
        return jsonify({
            'success': False,
            'message': '患者不存在'
        }), 404
    
    # 如果更新身份证号，检查是否与其他患者冲突
    if 'idNumber' in data and data['idNumber'] != patient['idNumber']:
        conflict = mongo.db.patients.find_one({'idNumber': data['idNumber'], '_id': {'$ne': patient['_id']}})
        if conflict:
            return jsonify({
                'success': False,
                'message': '该身份证号已被其他患者使用'
            }), 400
    
    # 准备更新数据
    update_data = data.copy()
    update_data['updatedAt'] = datetime.datetime.utcnow()
    
    # 更新数据库
    result = mongo.db.patients.update_one(
        {'_id': patient['_id']},
        {'$set': update_data}
    )
    
    if result.modified_count == 0:
        return jsonify({
            'success': False,
            'message': '患者信息更新失败'
        }), 500
    
    return jsonify({
        'success': True,
        'message': '患者信息更新成功',
        'data': {
            'id': str(patient['_id']),
            'patientId': patient['patientId'],
            'name': patient.get('name', data.get('name', '')),
            'updatedAt': update_data['updatedAt'].isoformat()
        }
    }), 200

@api_bp.route('/patients/<id>', methods=['DELETE'])
@jwt_required()
@permission_required('patient:delete')
def delete_patient(id):
    """删除患者（通常只是将患者标记为不活跃）"""
    # 查找患者
    patient = None
    if ObjectId.is_valid(id):
        patient = mongo.db.patients.find_one({'_id': ObjectId(id)})
    
    if not patient:
        patient = mongo.db.patients.find_one({'patientId': id})
    
    if not patient:
        return jsonify({
            'success': False,
            'message': '患者不存在'
        }), 404
    
    # 实际上我们只是将患者标记为不活跃，而不是真正删除
    result = mongo.db.patients.update_one(
        {'_id': patient['_id']},
        {
            '$set': {
                'activeStatus': False,
                'updatedAt': datetime.datetime.utcnow()
            }
        }
    )
    
    if result.modified_count == 0:
        return jsonify({
            'success': False,
            'message': '患者删除失败'
        }), 500
    
    return jsonify({
        'success': True,
        'message': '患者删除成功',
        'data': None
    }), 200

@api_bp.route('/patients/<id>/medical-records', methods=['GET'])
@jwt_required()
@permission_required('medical_record:read')
def get_patient_medical_records(id):
    """获取患者病历列表"""
    # 查找患者
    patient = None
    if ObjectId.is_valid(id):
        patient = mongo.db.patients.find_one({'_id': ObjectId(id)})
    
    if not patient:
        patient = mongo.db.patients.find_one({'patientId': id})
    
    if not patient:
        return jsonify({
            'success': False,
            'message': '患者不存在'
        }), 404
    
    # 获取分页参数
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'visitDate')
    order = request.args.get('order', 'desc')
    
    # 确定排序
    sort_direction = -1 if order.lower() == 'desc' else 1
    
    # 查询医疗记录
    patient_id = str(patient['_id'])
    records_cursor = mongo.db.medical_records.find(
        {'patientId': patient_id}
    ).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(records_cursor, page, limit)
    
    # 标准化数据
    normalized_items = []
    for record in paginated_data['items']:
        # 获取科室名称
        department_name = ''
        if 'departmentId' in record:
            dept_id = record['departmentId']
            if isinstance(dept_id, str) and ObjectId.is_valid(dept_id):
                dept_id = ObjectId(dept_id)
            department = mongo.db.departments.find_one({'_id': dept_id})
            if department:
                department_name = department.get('name', '')
        
        # 获取医生姓名
        doctor_name = ''
        if 'doctorId' in record:
            doc_id = record['doctorId']
            if isinstance(doc_id, str) and ObjectId.is_valid(doc_id):
                doc_id = ObjectId(doc_id)
            doctor = mongo.db.doctors.find_one({'_id': doc_id})
            if doctor:
                doctor_name = doctor.get('name', '')
        
        # 简化的记录信息
        simple_record = {
            'id': str(record['_id']),
            'recordId': record.get('recordId', ''),
            'visitDate': record.get('visitDate', ''),
            'departmentName': department_name,
            'doctorName': doctor_name,
            'diagnosis': [d.get('name', '') for d in record.get('diagnosis', [])],
            'status': record.get('status', ''),
            'createdAt': record.get('createdAt', '')
        }
        normalized_items.append(simple_record)
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'medicalRecords': normalized_items
        }
    }), 200